#ifndef LaneLayer_h__
#define LaneLayer_h__

#include "map_minedatarender/MineLayer.h"
#include "map_minedataset/Section.h"

namespace Mine
{
	class LaneSectionBase
	{
		friend class CLaneRenderObject;
	public:
		LaneSectionBase()
			:m_top_pts(new osg::Vec3Array), m_body_pts(new osg::Vec3Array),
			m_section_normal(0.f, 1.0f, 0.0f), m_section_up(0.0, 0.0, 1.0)
		{
		}

		virtual ~LaneSectionBase(){};
	public:
		virtual void setParam(const std::map<std::string,std::string>& param) {};

		int getTopVerticCount() { return m_top_pts->size(); }
		int getBodyVerticCount() { return m_body_pts->size(); }

		float getTopVerticTextureCoord(int index) const
		{
			float v = 0.0f;
			if (index < m_top_pts_texture_cord.size())
			{
				v = m_top_pts_texture_cord[index];
			}
			return v;
		}
		float getBodyVerticTextureCoord(int index) const
		{
			float v = 0.0f;
			if (index < m_body_pts_texture_cord.size())
			{
				v = m_body_pts_texture_cord[index];
			}
			return v;
		}

		virtual float getWidth() { return 0.f; }
		virtual float getHeight() { return 0.f; }
		virtual const osg::Vec3& getNormal() const { return m_section_normal; }
		virtual const osg::Vec3& getUpDir() const { return m_section_up; }
	public:
		virtual void createSectionPts() = 0;

	protected:
		osg::ref_ptr<osg::Vec3Array> m_top_pts;
		osg::ref_ptr<osg::Vec3Array> m_body_pts;
		std::vector<float> m_top_pts_texture_cord;
		std::vector<float> m_body_pts_texture_cord;
		osg::Vec3 m_section_normal;
		osg::Vec3 m_section_up;
	};

	class LaneWaySectionRect :public LaneSectionBase
	{
	public:
		LaneWaySectionRect(){};
		~LaneWaySectionRect(){};
	public:
		virtual void setParam(const std::map<std::string, std::string>& param) override;
		virtual void createSectionPts() override;
		virtual float getWidth() override { return m_width; }
		virtual float getHeight() override { return m_height; }
	private:
		float m_width = 3.f;
		float m_height = 3.f;
	};

	class LaneWaySectionArc :public LaneSectionBase
	{
	public:
		LaneWaySectionArc(){};
		~LaneWaySectionArc(){};
	public:
		virtual void setParam(const std::map<std::string, std::string>& param) override;
		virtual void createSectionPts() override;
		virtual float getWidth() override { return m_width; }
		virtual float getHeight() override { return m_height + m_top_height; }

	private:
		float m_width = 3.f;
		float m_height = 3.f;
		float m_top_height = 1.f;
		int   m_arc_segment = 16;
	};

	class LaneSectionCreator
	{
	public:
		static LaneSectionBase* createSection(SectionType type, const std::map<std::string,std::string>& param);
	};

	class MAP_MINEDATARENDER_EXPORT CLaneRenderObject
		: public CMineRenderObject
	{
	public:
		CLaneRenderObject(osg::ref_ptr<osg::Group> in_pParentNode);
		virtual ~CLaneRenderObject();

	public:
		virtual bool clip(const osg::Plane& plane) override;
		virtual bool clip(const osg::Vec3& startPt, const osg::Vec3& endPt) override;
		virtual bool clip(const std::vector<osg::Vec3>& pts) override;		virtual bool clearClip() override;

	protected:
		virtual osg::ref_ptr<osg::Node> createNode() override;
		virtual void onUnload() override;

	private:
		bool mIsClip = false;
		osg::Plane mClipPlane;
		osg::ClipNode* mClipNode = nullptr;
		std::vector<osg::Geometry*> mGeometrys;

		std::vector<osg::Vec3> mClipPts;
	};

	class MAP_MINEDATARENDER_EXPORT CLaneLayer
		: public Mine::CMineLayer
	{
	public:
		CLaneLayer();

		virtual ~CLaneLayer();
	protected:

		virtual DataRender::IRenderObject* createRenderObject(DataManager::IFeature* in_pFeature, osg::ref_ptr<osg::Group> in_pParentNode);

	};
}
#endif // LaneLayer_h__